﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports roncliProductions.LibWowArmory.Character.Statistics.Category
Imports System
Imports System.Collections.ObjectModel
Imports System.Globalization
Imports System.IO
Imports System.Linq
Imports System.Web
Imports System.Xml.Serialization

Namespace roncliProductions.LibWowArmory.Character.Statistics

    Public Class CharacterStatistics
        Inherits WowArmoryData

#Region "Declarations"

        Private csPage As New Schema.page
        Private sRecentStatistics As New Collection(Of Statistic)
        Private cCategories As New Collection(Of CategoryInfo)

#End Region

        ''' <summary>
        ''' The realm the character is on
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Realm As String

        ''' <summary>
        ''' The name of the character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Name As String

        ''' <summary>
        ''' The URL that will be used to retrieve the character's statistics from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property URL As String
            Get
                Return String.Format(CultureInfo.InvariantCulture, "http://www.wowarmory.com/character-statistics.xml?r={0}&n={1}", Realm, Name)
            End Get
        End Property

        ''' <summary>
        ''' Indicates to the inherited class that this request does not require login
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property RequiresLogin As Boolean
            Get
                Return False
            End Get
        End Property

        ''' <summary>
        ''' The most recent statistics earned by this character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RecentStatistics As Collection(Of Statistic)
            Get
                Return sRecentStatistics
            End Get
        End Property

        ''' <summary>
        ''' The statistic categories for this character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Categories As Collection(Of CategoryInfo)
            Get
                Return cCategories
            End Get
        End Property

        ''' <summary>
        ''' A constructor to load a character's statistics by realm and character name
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <param name="strName"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal strRealm As String, ByVal strName As String)
            Me.Realm = strRealm
            Me.Name = strName
            Load()
        End Sub

        ''' <summary>
        ''' Loads the character's statistics from the armory
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            Dim strKey As String = String.Format(CultureInfo.InvariantCulture, "LibWowArmory.CharacterStatistics.{0}.{1}", Realm, Name)
            If Cache.Cache(strKey) Is Nothing Then
                MyBase.Retrieve()

                Dim xsSerializer As New XmlSerializer(csPage.GetType)

                Using srXML As New StringReader(MyBase.Data)
                    csPage = CType(xsSerializer.Deserialize(srXML), Schema.page)
                End Using

                Cache.Cache.Insert(strKey, csPage, Nothing, Date.UtcNow.AddDays(1), Nothing, Caching.CacheItemPriority.Normal, Nothing)
            Else
                csPage = CType(Cache.Cache(strKey), Schema.page)
            End If

            If csPage Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve statistics for does not exist.")
            End If
            If csPage.characterInfo Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve statistics for does not exist.")
            End If
            If csPage.characterInfo.First.character Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve statistics for does not exist.")
            End If
            If csPage.statistics Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve statistics for does not exist.")
            End If

            For Each sStatistic As Schema.statistic In csPage.statistics.First.summary.First.statistic
                sRecentStatistics.Add(New Statistic(sStatistic.id, sStatistic.name, sStatistic.quantity))
            Next

            For Each cCategory As Schema.rootCategories_category In csPage.statistics.First.rootCategories.First.category
                cCategories.Add(New CategoryInfo(cCategory.id, cCategory.name, (From c In cCategory.category Select New SubcategoryInfo(c.name)).ToCollection))
            Next
        End Sub

        ''' <summary>
        ''' A character's statistics for a single category
        ''' </summary>
        ''' <param name="cCategory"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function CategoryStatistics(ByVal cCategory As CategoryInfo) As CharacterStatisticsCategory
            If cCategory Is Nothing Then Return Nothing
            Return New CharacterStatisticsCategory(Realm, Name, cCategory.CategoryID)
        End Function

    End Class

End Namespace